package com.dcms.staticizing.interceptor;

import com.dcms.staticizing.service.IStaticizingService;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang.StringUtils;
import org.apache.log4j.Logger;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.List;

/**
 * ClassName: StaticizingInterceptor
 * 所属功能模块:  静态化网页模块
 * 功能描述:
 *
 * @author zhouyijin
 * @Date 2018年02月19日 19:13
 * @since Ver 1.0
 */
public class StaticizingInterceptor implements HandlerInterceptor {

    private static final Logger logger = Logger.getLogger(StaticizingInterceptor.class);

    /**
     * 提供静态化页面功能的service
     * 这里目前只实现了个简单版本的SimpleStaticizingService
     * SimpleStaticizingService使用了ehcache作为缓存,如果以后还有其他需求再做其他实现类
     */
    private IStaticizingService staticizingService;

    /**
     * 不做拦截的url
     * 也就是这些url即使做了静态化页面,也不会生效
     * 这里都是相对路径,且不包含项目名
     */
    private List<String> exemptUrls;


    /**
     * 这里进行判断:
     *  1.如果此url是不需要被静态化的,则正常请求
     *  2.如果此请求的页面已经被静态化了,则直接写入静态化的html
     *  3.如果此请求的页面没有静态化,则正常请求
     * @param httpServletRequest
     * @param httpServletResponse
     * @param o
     * @return 返回true表示正常走业务链
     *          返回false表示直接拦截了,这里就直接返回静态化的页面
     * @throws Exception
     */
    @Override
    public boolean preHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o) throws Exception {
        String url = httpServletRequest.getRequestURI();
        logger.debug(url);
        //检查如果请求的url是配置好的不需要做静态化的页面,则直接放行,不返回静态化的页面
        if (CollectionUtils.isNotEmpty(exemptUrls)){
            for (String exemptUrl:exemptUrls) {
                if (exemptUrl.equals(url)){
                                        logger.info(httpServletRequest.getRemoteAddr()+"--> 访问 --> "+url+" :不需要静态化的页面!");
                    return true;
                }
            }
        }
        //根据url来从 staticizingService 中查询是否有静态化的页面
        String result = staticizingService.getStaticizedHtml(url);
        if (StringUtils.isNotEmpty(result)){
            httpServletResponse.setHeader("Content-Type","text/html;charset=UTF-8");
            httpServletResponse.getWriter().write(result);
            logger.info(httpServletRequest.getRemoteAddr()+"--> 访问 --> "+url+" :返回静态化页面!");
            return false;
        }
        return true;
    }

    @Override
    public void postHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, ModelAndView modelAndView) throws Exception {
        //todo 在业务处理器处理请求执行完成后,生成视图之前执行的拦截
    }

    @Override
    public void afterCompletion(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, Exception e) throws Exception {
        //todo 在DispatcherServlet完全处理完请求后被调用,可用于清理资源等    当有拦截器抛出异常时,会从当前拦截器往回执行所有的拦截器的afterCompletion()
    }

    public IStaticizingService getStaticizingService() {
        return staticizingService;
    }

    public void setStaticizingService(IStaticizingService staticizingService) {
        this.staticizingService = staticizingService;
    }

    public List<String> getExemptUrls() {
        return exemptUrls;
    }

    public void setExemptUrls(List<String> exemptUrls) {
        this.exemptUrls = exemptUrls;
    }
}
